#!/usr/bin/env python
# $Id: basic_ftpd.py 693 2010-05-18 18:10:22Z g.rodola $

"""
A basic FTP server which uses a DummyAuthorizer for managing 'virtual
users', setting a limit for incoming connections.
"""

import os,time
from pynotify import Notification
from pyftpdlib import ftpserver
#import threading as T
from functools import wraps
from utils import *
from multiprocessing import Event

class simplelog(object):
    def __init__(self,fname,string='{0} {1}\n'):
        self.string=string
        try:
            self.fd=open(fname,'a')
        except Exception,e:
            print 'file %s not openable!!' %fname
            print 'abort log writer'
            raise Exception
        self.now = lambda: time.strftime ("[%Y-%m-%d %H:%M:%S]")
    def __call__(self,msg):
        self.fd.write(self.string.format(self.now(),msg))    
        self.fd.flush()
    def __del__(self):
        self.fd.close()
        
def ftphandler_factory(notification_system):
    """
        This function return a properly set up class to override the 
        default FTPHandler
        Since we can not instantiate such class, we can not do that
        by standart __init__(self,args)
    """
    
    ns=notification_system
    class MyFTPHandler(ftpserver.FTPHandler):
        
        cmd_wrap_list=['RETR','APPE','STOU','STOR']
        for cmd in cmd_wrap_list:
            setattr(ftpserver.FTPHandler,'ftp_'+cmd,show_before_after(getattr(ftpserver.FTPHandler,'ftp_'+cmd)))
        #~ 
        #@run_async
        def on_login(self,user):
            ns.show("<b>%s</b> logged in" %user)
        #~ 
        #~ def on_logout(self,user):
            #~ ns.show("<b>%s</b> logged out" %user)
        #~ 
        #@run_async
        def on_file_sent(self,fn):
            ns.show("sent file: %s" %fn)
    return MyFTPHandler

class myserver(ftpserver.FTPServer):
    def __init__(self,port,users,caller):
        #T.Thread.__init__(self)
        
        self.e=Event()
        print 'evento',self.e.is_set()
        self.myport=port
        self.users=users
        self.caller=caller
        self.ExitNow=False
        # users: (username,pw,homedir,perm)
        #     eg: ('Goofy','pippi','....','elradfmw')
        self.ServerName='ShareMeserver'
        print self.myport
        
    def __del__(self):
        print "Politely deleting the server"
        self.stop()
        
    def stop(self):
       #from os import kill
        #from signal import SIGINT
        #kill(self.run.pid,SIGINT)
        #self.close_all()
        print 'setting event'
        self.e.set()

    @run_async
    def _run(self):
        print "server started"
        ftpserver.log = simplelog('%s.log' %self.ServerName)
        ftpserver.logline = simplelog('%s.line.log' %self.ServerName)
        ftpserver.logerror= simplelog('%s.err.log' %self.ServerName)
    
        # Instantiate a dummy authorizer for managing 'virtual' users
        authorizer = ftpserver.DummyAuthorizer()
    
        # Define a new user having full r/w permissions and a read-only
        # anonymous user
     
        for i in self.users:
            authorizer.add_user(i[0], i[1], i[2],i[3])

        # perm='elradfmw')
        #authorizer.add_anonymous('/home/astyonax/qBT_dir')
    
        # Instantiate FTP handler class
        ftp_handler = ftphandler_factory(self.caller.n)
        ftp_handler.authorizer = authorizer
    
        # Define a customized banner (string returned when client connects)
        ftp_handler.banner = "ShareMe share based on pyftpdlib %s." %ftpserver.__ver__
    
        # Specify a masquerade address and the range of ports to use for
        # passive connections.  Decomment in case you're behind a NAT.
        # ftp_handler.masquerade_address = '192.168.0.2'
        # ftp_handler.passive_ports = range(60000, 65535)
    
        # Instantiate FTP server class and listen to 0.0.0.0
        address = ('', self.myport)
        ftpserver.FTPServer.__init__(self,address, ftp_handler,self.e)
    
        # set a limit for connections
        self.max_cons = 256
        self.max_cons_per_ip = 5
       
        # start ftp server
        self.serve_forever()
      
        
    def __call__(self):
        self.run=self._run()
        
